using MediatR;
using S.O.Api.Read.Application.Command.Medical;
using S.O.Domain.Dto.Output;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;

namespace S.O.Api.Read.Application.Handler.Medical
{
    /// <summary>
    /// 获取医疗卡记录列表处理器
    /// 负责查询和返回医疗卡办理记录
    /// </summary>
    public class GetMedicalCardListHandler : IRequestHandler<GetMedicalCardListCommand, APIResult<List<MedicalCardDto>>>
    {
        /// <summary>
        /// 医疗卡信息仓储
        /// </summary>
        private readonly IBaseRepository<MedicalCardModel> _medicalCardRepository;
        
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<GetMedicalCardListHandler> _logger;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="medicalCardRepository">医疗卡信息仓储</param>
        /// <param name="logger">日志记录器</param>
        public GetMedicalCardListHandler(
            IBaseRepository<MedicalCardModel> medicalCardRepository,
            ILogger<GetMedicalCardListHandler> logger)
        {
            _medicalCardRepository = medicalCardRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取医疗卡记录列表命令
        /// </summary>
        /// <param name="request">查询命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>医疗卡记录列表</returns>
        public async Task<APIResult<List<MedicalCardDto>>> Handle(GetMedicalCardListCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation($"开始查询医疗卡记录，查询条件: PatientId={request.PatientId}, CardNo={request.CardNo}, IdCard={request.IdCard}");
                
                // 构建查询条件
                var query = _medicalCardRepository.GetALL()
                    .Where(x => !x.IsDeleted);
                
                // 按患者ID筛选
                if (request.PatientId.HasValue)
                {
                    query = query.Where(x => x.PatientId == request.PatientId.Value);
                }
                
                // 按医疗卡号筛选
                if (!string.IsNullOrWhiteSpace(request.CardNo))
                {
                    query = query.Where(x => x.CardNo.Contains(request.CardNo));
                }
                
                // 按身份证号筛选
                if (!string.IsNullOrWhiteSpace(request.IdCard))
                {
                    query = query.Where(x => x.IdCard.Contains(request.IdCard));
                }
                
                // 按患者姓名筛选
                if (!string.IsNullOrWhiteSpace(request.PatientName))
                {
                    query = query.Where(x => x.PatientName.Contains(request.PatientName));
                }
                
                // 按办卡状态筛选
                if (!string.IsNullOrWhiteSpace(request.CardStatus))
                {
                    query = query.Where(x => x.CardStatus == request.CardStatus);
                }
                
                // 按日期范围筛选
                if (request.StartDate.HasValue)
                {
                    query = query.Where(x => x.IssueDate >= request.StartDate.Value);
                }
                
                if (request.EndDate.HasValue)
                {
                    query = query.Where(x => x.IssueDate <= request.EndDate.Value.AddDays(1));
                }
                
                // 排序（按创建时间倒序）
                query = query.OrderByDescending(x => x.CreateTime);
                
                // 分页
                var totalCount = query.Count();
                var medicalCards = query
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToList();
                
                // 转换为DTO
                var result = medicalCards.Select(card => new MedicalCardDto
                {
                    Id = card.Id,
                    CardNo = card.CardNo,
                    PatientId = card.PatientId,
                    PatientName = card.PatientName,
                    IdCard = MaskIdCard(card.IdCard), // 脱敏处理
                    Phone = MaskPhone(card.Phone), // 脱敏处理
                    CardType = card.CardType,
                    CardFee = card.CardFee,
                    CardStatus = card.CardStatus,
                    IssueDate = card.IssueDate,
                    ActivateDate = card.ActivateDate,
                    ExpiryDate = card.ExpiryDate,
                    Operator = card.Operator,
                    IssueLocation = card.IssueLocation,
                    IsFirstTime = card.IsFirstTime,
                    OriginalCardNo = card.OriginalCardNo,
                    IsValid = card.IsValid,
                    CreateTime = card.CreateTime
                }).ToList();
                
                _logger.LogInformation($"查询医疗卡记录成功，共找到 {totalCount} 条记录，返回 {result.Count} 条");
                
                return new APIResult<List<MedicalCardDto>>
                {
                    Code = APIEnums.Success,
                    Data = result,
                    Msg = $"查询成功，共 {totalCount} 条记录"
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询医疗卡记录时发生异常");
                return new APIResult<List<MedicalCardDto>>
                {
                    Code = APIEnums.Error,
                    Msg = "查询医疗卡记录失败"
                };
            }
        }
        
        /// <summary>
        /// 身份证号脱敏处理
        /// </summary>
        /// <param name="idCard">身份证号</param>
        /// <returns>脱敏后的身份证号</returns>
        private string MaskIdCard(string idCard)
        {
            if (string.IsNullOrWhiteSpace(idCard) || idCard.Length < 8)
                return idCard;
            
            return idCard.Substring(0, 4) + "****" + idCard.Substring(idCard.Length - 4);
        }
        
        /// <summary>
        /// 手机号脱敏处理
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <returns>脱敏后的手机号</returns>
        private string MaskPhone(string phone)
        {
            if (string.IsNullOrWhiteSpace(phone) || phone.Length < 7)
                return phone;
            
            return phone.Substring(0, 3) + "****" + phone.Substring(phone.Length - 4);
        }
    }
}